package com.longwen.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/****
 * Metex是一个独占锁的自定义同步组件,它在同一时刻只允许一个线程占有锁。
 */

public class Mutex implements Lock {

	// 静态内部类，自定义同步器
	private static class Sync extends AbstractQueuedSynchronizer {

		
		private static final long serialVersionUID = 1L;

		// 是否处于占用状态
		@Override
		protected boolean isHeldExclusively() {
			return getState() == 1;

		}

		// 当状态为0都时候获取锁
		@Override
		public boolean tryAcquire(int acquires) {
			if (compareAndSetState(0, 1)) {
				setExclusiveOwnerThread(Thread.currentThread());
				return true;
			}
			return false;
		}

		// 释放锁，将状态设置为0
		@Override
		protected boolean tryRelease(int releases) {

			if (getState() == 0) {
				throw new IllegalMonitorStateException();
			}
			setExclusiveOwnerThread(null);
			setState(0);
			return true;

		}

		// 返回一个Condition，每个condition都包含了一个condition队列
		Condition newConditino() {
			return new ConditionObject();
		}

	}

	// 将操作代理到Sync上即可
	private final Sync sync = new Sync();

	@Override
	public void lock() {
		// TODO Auto-generated method stub
		sync.acquire(1);

	}

	@Override
	public void lockInterruptibly() throws InterruptedException {
		// TODO Auto-generated method stub
		sync.acquireInterruptibly(1);

	}

	@Override
	public boolean tryLock() {
		// TODO Auto-generated method stub
		return sync.tryAcquire(1);
	}

	@Override
	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
		// TODO Auto-generated method stub
		return sync.tryAcquireNanos(1, unit.toNanos(time));
	}

	@Override
	public void unlock() {
		// TODO Auto-generated method stub
		sync.release(1);

	}
	
	public boolean isLocked()
	{
		return sync.isHeldExclusively();
	}
	
	public boolean hasQueuedThreds(){
		return sync.hasQueuedThreads();
	}

	@Override
	public Condition newCondition() {
		// TODO Auto-generated method stub
		return sync.newConditino();
	}

}
